/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.XmlDataBase;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import org.jopendocument.dom.OOUtils;
import org.jopendocument.dom.spreadsheet.Sheet;
import org.jopendocument.dom.spreadsheet.SpreadSheet;

/**
 * Used for importing ODF files into the database and exporting XML files from the database.
 * 
 * @author Adam
 */
public class ODFTransformation {
    
    public ODFTransformation() {};
    
    /**
     * Exports the given collection of mediums into the ODF table, stores it into the file "output.ods"
    public void exportODF(Collection<Medium> mediums, String filename) {
        
     * and automatically opens the file.
     * 
     * @param mediums collection of mediums that are about to be exported
     * @return nothing
     * 
     * @throws NullPointerException if the given collection is null
     */
    public void exportODF(Collection<Medium> mediums, String filename) {
        
        if (mediums == null) throw new NullPointerException("Given parameter is null.");
        if (mediums.isEmpty()) return;
        
        File output = new File(filename);
        Object[] row = new Object[] {"Name/Title", "Type/Format", "Genre", "Languages", "Length", "Note"};
        DefaultTableModel model = new DefaultTableModel(row, 0);
        
        for (Medium medium : mediums) {
            model.setRowCount(model.getRowCount() + 1);
            
            row = new Object[] {medium.getName(), medium.getType()};
            model.addRow(row);

            Set<Movie> movies = medium.getMovies();
            for (Movie movie : movies) {
                Collection<String> langs = movie.getLanguages();
                String langConcat = "";

                for (String lang : langs) {
                    if (!langConcat.equals("")) langConcat += ",";
                    langConcat += lang;
                }
                row = new Object[] {movie.getTitle(), movie.getFormat(), movie.getGenre(), langConcat, movie.getLength(), movie.getNote()};

                model.addRow(row);
            }
        }
        try {
            SpreadSheet.createEmpty(model).saveAs(output);
            OOUtils.open(output);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
    public void exportODF(Collection<String> ids, MediumManager manager,String filename) throws NullPointerException, DatabaseException {
     * Exports the given collection of medium IDs into the ODF table, stores it into the file "output.ods"
     * and automatically opens the file.
     * 
     * @param ids      collection of medium IDs that should be exported
     * @param manager  medium manager that is to be used for extraction mediums according to their IDs
     * 
     * @throws NullPointerException if the given collection of IDs a is null
     * @throws DatabaseException if one of the given IDs are wrong (no medium with such ID was found in DB)
     */
    public void exportODF(Collection<String> ids, MediumManager manager,String filename) throws NullPointerException, DatabaseException {
        
        if (ids == null || manager == null) throw new NullPointerException("Given parameter is null.");        
        Collection<Medium> mediums = new ArrayList<Medium>();
        
        for (String id : ids) {
            mediums.add(manager.getMediumById(id));
        }        
        this.exportODF(mediums, filename);
    }
    
    /**
     * Imports mediums from the given ODF file into the database.
     * 
     * @param input   ODF file that contains a table with mediums that will be imported into the database
     * @param manager medium manager that will be used for storing mediums into the database
     * 
     * @throws NullPointerException if the given file is null
     */
    public void importODF(File input, MediumManager manager) {
        if (input == null) throw new NullPointerException("Given parameter is null.");
        
        Sheet sheet = null;
        try {
            sheet = SpreadSheet.createFromFile(input).getSheet(0);
        } catch (IOException ex) {
            Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        TableModel model = sheet.getTableModel(0, 2);
        int i = 0;
        
        while ((i < model.getRowCount()) && (!model.getValueAt(i, 0).toString().equals(""))) {
            Medium medium = new Medium();
            Set<Movie> movies = new HashSet<Movie>();
            
            medium.setName(model.getValueAt(i, 0).toString());
            medium.setType(model.getValueAt(i, 1).toString());
            i++;

            while ((i < model.getRowCount()) && (!model.getValueAt(i, 0).toString().equals(""))) {
                Movie movie = new Movie();
                
                movie.setTitle(model.getValueAt(i, 0).toString());
                movie.setFormat(model.getValueAt(i, 1).toString());
                movie.setGenre(model.getValueAt(i, 2).toString());

                List<String> langs = new ArrayList<String>();
                String languages = model.getValueAt(i, 3).toString();
                StringTokenizer tokens = new StringTokenizer(languages, ",");
                while (tokens.hasMoreTokens()) {
                    String lang = tokens.nextToken();
                    langs.add(lang);
                }
                movie.setLanguages(langs);

                Calendar cal = (Calendar)model.getValueAt(i, 4);
                movie.setLength(String.format("%02d", cal.get(Calendar.HOUR_OF_DAY))
                        +":"+String.format("%02d", cal.get(Calendar.MINUTE))+":"
                        +String.format("%02d", cal.get(Calendar.SECOND)));
                movie.setNote(model.getValueAt(i, 5).toString());
                movies.add(movie);
                i++;
            }
            medium.setMovies(movies);
            
            try {
                manager.createMedium(medium);
            } catch (DatabaseException ex) {
                Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NullPointerException ex) {
                Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ODFTransformation.class.getName()).log(Level.SEVERE, null, ex);
            }
            i++;
        }
    }
    
}
